home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
asmbler.arc
/
DETAB.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-11-19
|
5KB
|
133 lines
COMMENT \
Filter a file, expanding tabs to blanks up to the next column which is a
multiple of 8.
Usage: detab <inputfile >outputfile
{Adapted from a disassembly of the IBM utility MORE.COM and commented
with a view to being a model for further simple filters.}
[20-Jan-84]
\
assume cs:detabc,ds:detabc,es:detabc,ss:detabc
detabc segment para public 'code'
include dos.inc
include ascii.inc
org 100h
MAXBUFFER equ 4096 ; Buffer size (freely variable)
detab:
mov ah,$DOS_GETVERSION
int $DOS
xchg ah,al
cmp ax,0200h ; DOS 2.00 or later?
jnb cont ; jump if version >= 2.00
mov dx,offset baddos
mov ah,$DOS_STROUT ; print string
int $DOS
mov ah,$DOS_EXIT
mov al,1 ; return code
int $DOS ; terminate
cont:
mov byte ptr numrows,25
mov ah,0fh ; request current video state
int $VIDEO
mov numcols,ah ; save number of columns on display
mov bx,$STDIN ; standard input handle
mov ah,$DOS_DUP ; dup handle
int $DOS
mov bp,ax ; save duplicate handle
mov ah,$DOS_CLOSE2 ; close standard input
int $DOS
mov bx,$STDERR ; standard error handle
mov ah,$DOS_DUP ; dup handle
int $DOS
nextbf:
cld ; clear direction flag
mov dx,offset buffer ; buffer address
mov cx,MAXBUFFER ; count of bytes to read
mov bx,bp ; duplicate of standard input handle
mov ah,$DOS_READ2 ; byte stream
int $DOS ; read a byte string
or ax,ax ; set condition flags based on byte count
jnz gotch ; jump if got some bytes
exit:
mov ah,$DOS_EXIT ; all done, no more data
mov al,0 ; return code
int $DOS ; terminate
gotch:
mov cx,ax ; byte count
mov si,dx ; buffer address ???
nextch:
lodsb ; load byte at 0(si), then increment si
cmp al,.CR ; Hit CR yet?
jne nocr ; Jump if not CR
mov byte ptr colnum,1 ; Was CR, set column_number = 1
jmp short printch ; go print the character
nocr:
cmp al,.LF ; Hit end-of-line yet?
jne nolf ; Jump if not LF
inc rownum ; Hit LF, increment row number
jmp short printch ; go print the character
nolf:
cmp al,.BS ; Hit backspace?
jne nobs ; Jump if not BS
cmp byte ptr colnum,1 ; At beginning of line?
jz printch ; Yes, just print character
dec colnum ; No, decrement column number because of BS
jmp short printch ; Go print the character
nobs:
cmp al,.HT ; Hit tab?
jne notab ; Jump if not tab.
mov ah,colnum ; Was tab, get column number
add ah,7 ; column number + 7
and ah,not 7 ; clear right 3 bits, effectively advancing
inc ah ; to multiple of 8, then add 1 more
mov colnum,ah ; and update column number
jmp short printch ; Go print the character
notab:
cmp al,.BEL ; Hit a bell?
je printch ; Yes, just print it
inc colnum ; Not special character, so just increment
mov ah,colnum ; column number and remember it
cmp ah,numcols ; At end of screen line yet?
jbe printch ; jump if not
inc rownum ; At end of screen line, so start a new row
mov byte ptr colnum,1 ; and reset to column 1
printch:
mov dl,al ; the character to output
mov ah,$DOS_CONOUT ; print char
int $DOS
mov ah,rownum
cmp ah,numrows ; At end of screen yet?
jb loopch ; Jump if not
mov byte ptr colnum,1 ; Reset row/column to home
mov byte ptr rownum,1 ; position
dec si ; Backup in buffer
inc cx ; and increase byte count (why ??)
loopch:
dec cx ; Reduce byte count since we just output one
jbe longbf ; Exit loop if count <= 0
jmp nextch ; Otherwise loop for next character
longbf:
jmp nextbf ; Loop for next buffer
numrows db 24 ; Default screen rows
numcols db 80 ; Default screen columns
rownum db 01 ; Starting screen row
colnum db 01 ; Starting screen column
db 00h,00h,00h,00h,00h
baddos db "DETAB: Incorrect DOS version"
db " -- must run under DOS 2.0 or later"
crlf db .CR,.LF,"$"
buffer db MAXBUFFER dup (0) ; Input buffer
detabc ends
end detab